<?php
// $Id$

/**
 * @file
 * Administration pages and callbacks for the guild module.
 */

// @todo Use or remove the destination query where applicable.
// if (isset($_REQUEST['destination'])) {
//   $destination = drupal_get_destination();
//   unset($_REQUEST['destination']);
// }

/**
 * Get the display name of available game modules.
 *
 * @return array An associative array with the module name as the key and
 * display name as the value.
 *
 * @see guild_get_point_systems()
 */
function guild_get_games() {
  $config = guild_game_config();
  $games = array();
  
  foreach ($config as $module => $info) {
    $games[$module] = $info['name'];
  }
  
  return $games;
}

/**
 * Form builder; Build the main settings form for the guild module.
 *
 * @see guild_admin_settings_form_submit()
 *
 * @ingroup forms
 */
function guild_admin_settings_form($form_state) {
  $selected_game = variable_get('guild_game_module', '');
  $game_modules = guild_get_games();
  
  // The selected game needs to be updated before the form is rebuilt after a sumbit.
  if (isset($form_state['post']['game_module']) && $form_state['post']['game_module']) {
    $selected_game = $form_state['post']['game_module'];
  }
  
  // @todo Determine if reinstalling a game module may not reset the proper field?
  
  // There are no game modules installed.
  if (empty($game_modules)) {
    $game_modules = array('' => t('(no modules found)'));
    $t_args = array('@enable-module' => url('admin/build/modules'));
    drupal_set_message(t('You can further customize the information this module uses by <a href="@enable-module">enabling a game module</a>.', $t_args), 'warning', FALSE);
  }
  // Either this is our first run, or we uninstalled our last game.
  else if ($selected_game == '' || !isset($game_modules[$selected_game])) {
    $game_modules = array_merge(array('' => t('(no game selected)')), $game_modules);
    drupal_set_message(t('A game module has not been selected. This module will have limited capabilities until a game module is set.'), 'warning', FALSE);
  }
  
  $form['general'] = array(
    '#type' => 'fieldset',
    '#title' => t('Guild information'),
    '#collapsible' => FALSE,
    '#weight' => -10
  );
  
  $form['general']['game_module'] = array(
    '#type' => 'select',
    '#title' => t('Game module'),
    '#options' => $game_modules,
    '#description' => t(
      'This will apply game specific settings to player and guild pages.<br />' .
      '<strong>Warning! Changing this setting after content has been created could result in the loss of data!</strong>'),
    '#default_value' => variable_get('guild_game_module', '')
  );
  
  $form['general']['game_server'] = array(
    '#type' => 'textfield',
    '#title' => t('Game server'),
    '#description' => t('The realm name your guild plays on.'),
    '#default_value' => variable_get('guild_game_server', ''),
    '#maxlength' => 32
  );
  
  $form['general']['guild_name'] = array(
    '#type' => 'textfield',
    '#title' => t('Guild name'),
    '#default_value' => variable_get('guild_guild_name', ''),
    '#maxlength' => 32
  );
  
  $form['player'] = array(
    '#type' => 'fieldset',
    '#title' => t('Player settings'),
    '#collapsible' => FALSE,
    '#weight' => -9
  );
  
  $form['player']['inactive_filter'] = array(
    '#type' => 'checkbox',
    '#title' => t('Filter inactive players from display listings'),
    '#description' => t(
      'Some pages can hide inactive players, potentially making guild listings much shorter. ' .
      'Disable this setting to list all players (best for small guilds).'
    ),
    '#default_value' => variable_get('guild_inactive_filter', FALSE)
  );
  
  // @todo Technically the automatic inactivity options are the same.
  // Perhaps one allows individual events and the other does not?
  $form['player']['auto_inactive'] = array(
    '#type' => 'item',
    '#title' => t('Automatic inactivity'),
    '#description' => t('Members who have not participated in a guild event after this period has elapsed will have their status automatically changed to inactive.')
  );
  
  $form['player']['auto_inactive'][0] = array(
    '#type' => 'radio',
    '#title' => t('Disable'),
    '#default_value' => 2,
    '#return_value' => 0,
    '#parents' => array('auto_inactive'),
    '#prefix' => '<div class="form-radios">'
  );
  
  $form['player']['auto_inactive']['days'] = array(
    '#prefix' => '<div class="container-inline form-item">',
    '#suffix' => '</div>'
  );
  
  $form['player']['auto_inactive']['days']['day_option'] = array(
    '#type' => 'radio',
    '#title' => t('Change status after'),
    '#default_value' => 2,
    '#return_value' => 1,
    '#parents' => array('auto_inactive')
  );
  
  $form['player']['auto_inactive']['days']['day_count'] = array(
    '#type' => 'textfield',
    '#field_suffix' => t('days'),
    '#default_value' => 14,
    '#maxlength' => 3,
    '#size' => 3
  );
  
  $form['player']['auto_inactive']['raids'] = array(
    '#prefix' => '<div class="container-inline form-item">',
    '#suffix' => '</div>'
  );
  
  $form['player']['auto_inactive']['raids']['raid_option'] = array(
    '#type' => 'radio',
    '#title' => t('Change status after'),
    '#default_value' => 2,
    '#return_value' => 2,
    '#parents' => array('auto_inactive')
  );
  
  $form['player']['auto_inactive']['raids']['raid_count'] = array(
    '#type' => 'textfield',
    '#field_suffix' => t('missed raids'),
    '#default_value' => 10, 
    '#maxlength' => 3,
    '#size' => 3,
    '#suffix' => '</div>'
  );
  
  // variable_get('guild_auto_inactive', TRUE)
  //$form['player']['auto_inactive'] = array(
  //  '#type' => 'checkbox',
  //  '#title' => t('Allow automatic inactivity'),
  //  '#description' => t('Members who have not participated in a guild event will have their status automatically changed to inactive.'),
  //  '#default_value' => TRUE
  //);
  
  // variable_get('guild_inactive_delay', 14)
  //$form['player']['inactive_delay'] = array(
  //  '#type' => 'textfield',
  //  '#title' => t('Inactive delay'),
  //  '#description' => t('Players will have their guild status changed to inactive after this period has elapsed, if automatic inactivity is enabled.'),
  //  '#field_suffix' => t('days'),
  //  '#default_value' => 14,
  //  '#maxlength' => 3,
  //  '#size' => 3
  //);
  
  $form['player']['players_per_page'] = array(
    '#type' => 'select',
    '#title' => t('Players per page'),
    '#description' => t('Default number of players displayed per page.'),
    '#options' => array(
      20 => t('20'),
      30 => t('30'),
      40 => t('40'),
      50 => t('50')
    ),
    '#default_value' => variable_get('guild_players_per_page', 50)
  );
  
  $form['buttons']['save'] = array(
    '#type' => 'submit',
    '#value' => t('Save configuration')
  );
  
  return $form;
}

function guild_admin_settings_form_validate($form, &$form_state) {
  $values = $form_state['values'];
  
  if (!is_numeric($values['day_count']) || $values['day_count'] <= 0) {
    form_set_error('day_count', t('The inactivity delay period must be a number and greater than 0.'));
  }
  
  if (!is_numeric($values['raid_count']) || $values['raid_count'] <= 0) {
    form_set_error('raid_count', t('The inactivity delay period must be a number and greater than 0.'));
  }
}

/**
 * 
 */
function guild_admin_settings_form_submit($form, &$form_state) {
  $settings = $form_state['values'];
  
  // @todo Notify other modules when the selected game has changed?
  variable_set('guild_game_module', $settings['game_module']);
  variable_set('guild_game_server', $settings['game_server']);
  variable_set('guild_guild_name', $settings['guild_name']);
  
  variable_set('guild_inactive_filter', $settings['inactive_filter']);
  variable_set('guild_players_per_page', $settings['players_per_page']);
  
  drupal_set_message(t('Guild settings have been updated.'));
}

/**
 * -----------------------------------------------------------------------------
 * REGION: Update options.
 * -----------------------------------------------------------------------------
 */

/**
 * Form builder; Create an "Update options" form for an administrator.
 *
 * @param string $type The type of update operations for the page.
 *
 * @return array A small form with a select box showing update options and an update button.
 */
function guild_admin_operations($type) {
  $form['update_type'] = array('#type' => 'hidden', '#value' => $type);
  
  $form['update'] = array(
    '#type' => 'fieldset',
    '#title' => t('Update options'),
    '#prefix' => '<div class="container-inline">',
    '#suffix' => '</div>'
  );
  
  $options = array();
  foreach (guild_update_operations($type) as $op => $value) {
    $options[$op] = $value['label'];
  }
  
  $op_default = array_shift(array_keys($options));
  $form['update']['operation'] = array(
    '#type' => 'select',
    '#options' => $options,
    '#default_value' => $op_default
  );
  
  $form['update']['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Update'),
    '#validate' => array('guild_operation_validate'),
    '#submit' => array('guild_operation_submit')
  );
  
  return $form;
}

/**
 * Provide update operations for a specified page.
 *
 * @param string $action The guild administration page.
 *
 * @return array An array containing supported operations. Each operation includes
 *   a label and if available, a callback used to execute the operation.
 */
function guild_update_operations($action) {
  switch ($action) {
    case 'events':
      $operations = array(
        'delete' => array(
          'label' => t('Delete the selected events'),
          'callback' => 'guild_delete_event',
          'file' => 'includes/guild.events.inc'
        )
      );
      break;
    case 'items':
      $operations = array(
        'delete' => array(
          'label' => t('Delete the selected items'),
          'callback' => 'guild_delete_item',
          'file' => 'includes/guild.items.inc'
        )
      );
      break;
    case 'raids':
      $operations = array(
        'delete' => array(
          'label' => t('Delete the selected raids'),
          'callback' => 'guild_delete_raid',
          'file' => 'includes/guild.raids.inc'
        )
      );
      break;
  }
  
  return $operations;
}

/**
 * Verify that a selection was made prior to executing an update operation.
 */
function guild_operation_validate($form, &$form_state) {
  $type = $form_state['values']['update_type'];
  
  $form_state['values'][$type] = array_diff($form_state['values'][$type], array(0));
  
  if (count($form_state['values'][$type]) == 0) {
    form_set_error('', t('Please select one or more items to perform the update on.'));
  }
}

/**
 * Execute an update operation on the selected items.
 *
 * @todo The function guild_operation_submit() has been tested, but not used.
 */
function guild_operation_submit($form, &$form_state) {
  $type = $form_state['values']['update_type'];
  
  // To allow custom operations, this could also be changed to something like:
  //   $operations = module_invoke_all('guild_admin_operations');
  $operations = guild_update_operations($type);
  $operation = $operations[$form_state['values']['operation']];
  
  // Invokes an operation callback with the selected items included as the first argument.
  $result = array_filter($form_state['values'][$type]);
  if ($function = $operation['callback']) {
    if (isset($operation['callback arguments'])) {
      $args = array_merge(array($result), $operation['callback arguments']);
    }
    else {
      $args = $result;
    }
    
    call_user_func_array($function, $args);
    
    //cache_clear_all();
  }
  else {
    // If there was no callback, we need to rebuild the form to get to the next step.
    $form_state['rebuild'] = TRUE;
  }
}

/**
 * Verify that the selected items should be deleted.
 */
function guild_operation_multiple_delete_confirm(&$form_state) {
  $type = $form_state['post']['update_type'];
  
  $counter = 0;
  $sql = _guild_load_sql($type);
  $form[$type] = array('#prefix' => '<ul>', '#suffix' => '</ul>', '#tree' => TRUE);
  
  // List all selected items.
  foreach (array_filter($form_state['post'][$type]) as $id => $value) {
    $result = db_fetch_object(db_query($sql['query'], $id));
    
    if (is_object($result) && is_numeric($result->$sql['id'])) {
      $form[$type][$result->$sql['id']] = array(
        '#type' => 'hidden',
        '#value' => $result->$sql['id'],
        '#prefix' => '<li>',
        '#suffix' => check_plain($result->$sql['name']) .'</li>'
      );
      
      $counter++;
    }
  }
  
  $form['operation'] = array('#type' => 'hidden', '#value' => 'delete');
  $form['update_type'] = array('#type' => 'hidden', '#value' => $type);
  
  if ($counter > 0) {
    return confirm_form($form, t('Are you sure?'), 'admin/guild/' . $type,
      '<p>' . t('The above items will be deleted. This action cannot be undone.') . '</p>',
      t('Delete'), t('Cancel'));
  }
  
  drupal_set_message(t('There were no items to delete.'));
  drupal_goto('admin/guild/' . $type);
}

/**
 * Delete the selected items.
 */
function guild_operation_multiple_delete_confirm_submit($form, &$form_state) {
  $type = $form_state['values']['update_type'];
  $sql = _guild_load_sql($type);
  
  // Get the operation's information for this update type.
  $operations = guild_update_operations($type);
  $operation = $operations[$form_state['values']['operation']];
  
  if ($form_state['values']['confirm']) {
    foreach ($form_state['values'][$type] as $id => $value) {
      $result = db_fetch_object(db_query($sql['query'], $id));
      
      // Include the callback file.
      if ($operation['file']) {
        require_once drupal_get_path('module', 'guild') . '/' . $operation['file'];
      }
      
      // Callback arguments aren't needed to delete stuff.
      $function = $operation['callback'];
      $function($result);
    }
    
    //cache_clear_all();
    drupal_set_message(t('The items have been deleted.'));
  }

  $form_state['redirect'] = 'admin/guild/' . $type;
  return;
}

/**
 * -----------------------------------------------------------------------------
 * REGION: Utilities and miscellaneous callbacks.
 * -----------------------------------------------------------------------------
 */

//function guild_player_autocomplete($string = '') {
//  $matches = array();
//  if ($string) {
//    $result = db_query_range(
//      "SELECT n.title FROM {node} n " .
//      "INNER JOIN {guild_member} m USING(nid) " .
//      "INNER JOIN {guild_rank} r USING(rank_id) " .
//      "WHERE LOWER(n.title) LIKE LOWER('%%%s%%') " .
//      "ORDER BY r.tier ASC", $string, 0, 10);
//    while ($player = db_fetch_object($result)) {
//      $matches[$player->title] = check_plain($player->title);
//    }
//  }
//  
//  drupal_json($matches);
//}
